
/**HEADER********************************************************************
* 
* Copyright (c) 2008 Freescale Semiconductor;
* All Rights Reserved
*
* Copyright (c) 2004-2010 Embedded Access Inc.;
* All Rights Reserved
*
* Copyright (c) 1989-2008 ARC International;
* All Rights Reserved
*
*************************************************************************** 
*
* THIS SOFTWARE IS PROVIDED BY FREESCALE "AS IS" AND ANY EXPRESSED OR 
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  
* IN NO EVENT SHALL FREESCALE OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, 
* INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, 
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING 
* IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF 
* THE POSSIBILITY OF SUCH DAMAGE.
*
**************************************************************************
*
* $FileName: mpc83xx_etsec_util.c$
* $Version : 3.8.1.0$
* $Date    : May-12-2011$
*
* Comments:
*
*   This file initializes the 83xx ethernet interface.
*
*END************************************************************************/

#include <mqx.h>
#include <bsp.h>
#include <bsp_prv.h>
#include <ethernet.h>
#include <enet.h>
#include <enetprv.h>
#include <mdio.h>
#include <mpc83xx_etsec_prv.h>


/*ISR*------------------------------------------------------------------
*
*  Function Name  : MPC83xx_etsec_ERR_ISR
*  Returned Value : void
*  Comments       :
*        Error ISR
*
*END*-----------------------------------------------------------------*/

void MPC83xx_etsec_ERR_ISR
   (
      /* [IN] the Ethernet state structure */
      ENET_CONTEXT_STRUCT_PTR  enet_ptr
   )
{ 
   MPC83XX_TSEC_CONTEXT_STRUCT_PTR  tsec_context_ptr;
   MPC83xx_ETSEC_STRUCT_PTR tsec_ptr;
   static uint_32          events = 0;

   tsec_context_ptr = enet_ptr->MAC_CONTEXT_PTR;
   tsec_ptr = tsec_context_ptr->TSEC_ADDRESS;
   
   events++;
   
} 


/*FUNCTION*-------------------------------------------------------------
*
*  Function Name  : MPC83xx_etsec_install_isr
*  Returned Value : ENET_OK or error code
*  Comments       :
*         
*
*END*-----------------------------------------------------------------*/

static boolean MPC83xx_etsec_install_isr( 
   ENET_CONTEXT_STRUCT_PTR enet_ptr, 
   uint_32                 int_num, 
   void _CODE_PTR_         isr ) 
{
   MPC83XX_TSEC_CONTEXT_STRUCT_PTR   etsec_context_ptr = (MPC83XX_TSEC_CONTEXT_STRUCT_PTR) enet_ptr->MAC_CONTEXT_PTR;
   uint_32  vector = MPC83xx_etsec_get_vector(enet_ptr->PARAM_PTR->ENET_IF->MAC_NUMBER, int_num);
   typedef void(*ISR_PTR)(pointer);
 
   // Save old ISR and data
   etsec_context_ptr->OLDISR_PTR[int_num]  = (void *)_int_get_isr(vector);
   etsec_context_ptr->OLDISR_DATA[int_num] = _int_get_isr_data(vector);

   if (_int_install_isr(vector, (ISR_PTR)isr, (pointer)enet_ptr)==NULL) {
      return FALSE;
   }

   return TRUE;
}


/*FUNCTION*-------------------------------------------------------------
*
*  Function Name  : MPC83xx_etsec_install_isrs
*  Returned Value :  
*  Comments       :
*        
*
*END*-----------------------------------------------------------------*/

boolean MPC83xx_etsec_install_isrs( ENET_CONTEXT_STRUCT_PTR enet_ptr  ) 
{
   boolean bOK;
   typedef void(*FC_INT_PTR);
   
   bOK = MPC83xx_etsec_install_isr(enet_ptr, MPC83xx_TSEC_TX_INT, (FC_INT_PTR)MPC83xx_etsec_TX_ISR);
   if (bOK) {
      bOK = MPC83xx_etsec_install_isr(enet_ptr, MPC83xx_TSEC_RX_INT, (FC_INT_PTR)MPC83xx_etsec_RX_ISR);
   }
   if (bOK) {
      bOK = MPC83xx_etsec_install_isr(enet_ptr, MPC83xx_TSEC_ERR_INT, (FC_INT_PTR)MPC83xx_etsec_ERR_ISR);
   }

   return bOK;
}

/*FUNCTION*-------------------------------------------------------------
*
*  Function Name  : MPC83xx_etsec_enable_ints
*  Returned Value :  
*  Comments       :
*        
*
*END*-----------------------------------------------------------------*/

boolean MPC83xx_etsec_enable_ints( ENET_CONTEXT_STRUCT_PTR enet_ptr  ) 
{
   _mpc83xx_enable_interrupt( MPC83xx_etsec_get_vector(enet_ptr->PARAM_PTR->ENET_IF->MAC_NUMBER, MPC83xx_TSEC_TX_INT));
   _mpc83xx_enable_interrupt( MPC83xx_etsec_get_vector(enet_ptr->PARAM_PTR->ENET_IF->MAC_NUMBER, MPC83xx_TSEC_RX_INT));
   _mpc83xx_enable_interrupt( MPC83xx_etsec_get_vector(enet_ptr->PARAM_PTR->ENET_IF->MAC_NUMBER, MPC83xx_TSEC_ERR_INT));
}


/*FUNCTION*-------------------------------------------------------------
*
*  Function Name  : MPC83xx_etsec_uninstall_isr
*  Returned Value :  
*  Comments       :
*        
*
*END*-----------------------------------------------------------------*/

static void MPC83xx_etsec_uninstall_isr( ENET_CONTEXT_STRUCT_PTR enet_ptr, uint_32 int_index  ) 
{
   MPC83XX_TSEC_CONTEXT_STRUCT_PTR    tsec_context_ptr = (MPC83XX_TSEC_CONTEXT_STRUCT_PTR) enet_ptr->MAC_CONTEXT_PTR;
   uint_32  vector = MPC83xx_etsec_get_vector(enet_ptr->PARAM_PTR->ENET_IF->MAC_NUMBER, int_index);
 
   typedef void( * FC_INT_PTR)(pointer);
   
   _mpc83xx_disable_interrupt(vector);
   
   if (tsec_context_ptr->OLDISR_PTR[int_index]) {
      _int_install_isr(vector, (FC_INT_PTR)tsec_context_ptr->OLDISR_PTR[int_index], tsec_context_ptr->OLDISR_DATA[int_index]);
      tsec_context_ptr->OLDISR_PTR[int_index] = NULL;
   }
}



/*FUNCTION*-------------------------------------------------------------
*
*  Function Name  : MPC83xx_etsec_uninstall_all_isrs
*  Returned Value :  
*  Comments       :
*        
*
*END*-----------------------------------------------------------------*/

void MPC83xx_etsec_uninstall_all_isrs( ENET_CONTEXT_STRUCT_PTR enet_ptr) 
{
   MPC83xx_etsec_uninstall_isr(enet_ptr, MPC83xx_TSEC_TX_INT);
   MPC83xx_etsec_uninstall_isr(enet_ptr, MPC83xx_TSEC_RX_INT);
   MPC83xx_etsec_uninstall_isr(enet_ptr, MPC83xx_TSEC_ERR_INT);
}


/*FUNCTION*-------------------------------------------------------------
* 
* Function Name    : MPC83xx_etsec_get_vector
* Returned Value   : MQX vector number for specified interrupt
* Comments         :
*    This function returns index into MQX interrupt vector table for
*    specified enet interrupt. If not known, returns 0.
*
*END*-----------------------------------------------------------------*/


uint_32 MPC83xx_etsec_get_vector(uint_32 device, uint_32 vector_index)
{ 
    uint_32 index = 0;

    if ((device <MPC83xx_ETSEC_DEVICE_COUNT) && (vector_index <MPC83xx_ETSEC_NUM_INTS)) {
      index = MPC83xx_etsec_vectors[device][vector_index];
    }

 	return index;
} 


/*FUNCTION*-------------------------------------------------------------
*
*  Function Name  : MPC83xx_etsec_free_context
*  Returned Value :  
*  Comments       :
*        
*
*END*-----------------------------------------------------------------*/

void MPC83xx_etsec_free_context( MPC83XX_TSEC_CONTEXT_STRUCT_PTR tsec_context_ptr ) 
{
   if (tsec_context_ptr) {
      if (tsec_context_ptr->TSEC_RX_RING_PTR) {
         _mem_free((pointer)tsec_context_ptr->TSEC_RX_RING_PTR);
      }
      if (tsec_context_ptr->TSEC_TX_RING_PTR) {
         _mem_free((pointer)tsec_context_ptr->TSEC_TX_RING_PTR);
      }
      if (tsec_context_ptr->RX_PCB_BASE) {
         _mem_free(tsec_context_ptr->RX_PCB_BASE);
      }
      _mem_free(tsec_context_ptr);
   }
}

